﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Text;
using Medianamik.Core.Configuration;

namespace Medianamik.Core.Urls
{
    [Serializable]
    public class MedianamikUrl : IMedianamikUrl, IEquatable<MedianamikUrl>
    {
        [NonSerialized]
        private static MedianamikConfigSection _config =
            (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        public MedianamikUrl(Guid websiteId, CultureInfo culture,
             string path, bool excludedFromIndexation)
            : this(ConfigManager.GetWebSite(websiteId, culture),
                culture, path, excludedFromIndexation)
        {

        }

        public MedianamikUrl(WebSite website, CultureInfo culture,
             string path, bool excludedFromIndexation)
        {
            website.DefaultCulture = culture;
            _websiteId = website.ID;
            _excludedFromIndexation = excludedFromIndexation;
            _culture = culture;
            _websitePrefix = website.Prefix;
            _originalPath = EnsurePathStartsWithSlash(path);
            _path = EnsurePathExtension(_originalPath);
            _excludedFromIndexation = excludedFromIndexation;
        }

        private readonly string _originalPath;
        public string OriginalPath
        {
            get { return _originalPath; }
        }

        private string EnsurePathStartsWithSlash(string path)
        {
            return path.StartsWith("/") ? path : "/" + path;
        }

        public MedianamikUrl(WebSite website, CultureInfo culture,
             string path, bool excludedFromIndexation, MedianamikConfigSection config)
            : this(website, culture, path, excludedFromIndexation)
        {
            _config = config;
        }

        private readonly Guid _websiteId;
        public Guid WebsiteId
        {
            get { return _websiteId; }
        }

        private readonly CultureInfo _culture;
        public CultureInfo Culture
        {
            get { return _culture; }
        }

        private readonly string _websitePrefix;
        public string WebsitePrefix
        {
            get { return _websitePrefix; }
        }

        private readonly string _path;
        public string Path
        {
            get { return _path; }
        }

        private readonly bool _excludedFromIndexation;
        public bool ExcludedFromIndexation
        {
            get { return _excludedFromIndexation; }
        }

        private string EnsurePathExtension(string path)
        {
            if (!path.EndsWith("/") && path.LastIndexOf('/') >= 0 &&
                   path.Substring(path.LastIndexOf('/')).IndexOf('.') < 0)
                return path + _config.DefaultPageExtension;

            return path;
        }

        public bool Equals(MedianamikUrl other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other._websiteId.Equals(_websiteId) && Equals(other._path, _path);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (MedianamikUrl)) return false;
            return Equals((MedianamikUrl) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (_websiteId.GetHashCode()*397) ^ _path.GetHashCode();
            }
        }

        public static bool operator ==(MedianamikUrl left, MedianamikUrl right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(MedianamikUrl left, MedianamikUrl right)
        {
            return !Equals(left, right);
        }
    }
}
